Skip to content

Commit

Permalink
Merge branch 'jk/empty-tree'
Browse files Browse the repository at this point in the history
* jk/empty-tree:
  add--interactive: handle initial commit better
  hard-code the empty tree object
  • Loading branch information
gitster committed Feb 21, 2008
2 parents 428ae2e + 18bc761 commit c484166
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 16 deletions.
55 changes: 39 additions & 16 deletions git-add--interactive.perl
Expand Up @@ -82,6 +82,19 @@ sub list_untracked {
my $status_fmt = '%12s %12s %s';
my $status_head = sprintf($status_fmt, 'staged', 'unstaged', 'path');

{
my $initial;
sub is_initial_commit {
$initial = system('git rev-parse HEAD -- >/dev/null 2>&1') != 0
unless defined $initial;
return $initial;
}
}

sub get_empty_tree {
return '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
}

# Returns list of hashes, contents of each of which are:
# VALUE: pathname
# BINARY: is a binary path
Expand All @@ -103,8 +116,10 @@ sub list_modified {
return if (!@tracked);
}

my $reference = is_initial_commit() ? get_empty_tree() : 'HEAD';
for (run_cmd_pipe(qw(git diff-index --cached
--numstat --summary HEAD --), @tracked)) {
--numstat --summary), $reference,
'--', @tracked)) {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
my ($change, $bin);
Expand Down Expand Up @@ -476,21 +491,27 @@ sub revert_cmd {
HEADER => $status_head, },
list_modified());
if (@update) {
my @lines = run_cmd_pipe(qw(git ls-tree HEAD --),
map { $_->{VALUE} } @update);
my $fh;
open $fh, '| git update-index --index-info'
or die;
for (@lines) {
print $fh $_;
if (is_initial_commit()) {
system(qw(git rm --cached),
map { $_->{VALUE} } @update);
}
close($fh);
for (@update) {
if ($_->{INDEX_ADDDEL} &&
$_->{INDEX_ADDDEL} eq 'create') {
system(qw(git update-index --force-remove --),
$_->{VALUE});
print "note: $_->{VALUE} is untracked now.\n";
else {
my @lines = run_cmd_pipe(qw(git ls-tree HEAD --),
map { $_->{VALUE} } @update);
my $fh;
open $fh, '| git update-index --index-info'
or die;
for (@lines) {
print $fh $_;
}
close($fh);
for (@update) {
if ($_->{INDEX_ADDDEL} &&
$_->{INDEX_ADDDEL} eq 'create') {
system(qw(git update-index --force-remove --),
$_->{VALUE});
print "note: $_->{VALUE} is untracked now.\n";
}
}
}
refresh();
Expand Down Expand Up @@ -956,7 +977,9 @@ sub diff_cmd {
HEADER => $status_head, },
@mods);
return if (!@them);
system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);
my $reference = is_initial_commit() ? get_empty_tree() : 'HEAD';
system(qw(git diff -p --cached), $reference, '--',
map { $_->{VALUE} } @them);
}

sub quit_cmd {
Expand Down
11 changes: 11 additions & 0 deletions sha1_file.c
Expand Up @@ -1845,6 +1845,15 @@ static struct cached_object {
} *cached_objects;
static int cached_object_nr, cached_object_alloc;

static struct cached_object empty_tree = {
/* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */
"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60"
"\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04",
OBJ_TREE,
"",
0
};

static struct cached_object *find_cached_object(const unsigned char *sha1)
{
int i;
Expand All @@ -1854,6 +1863,8 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)
if (!hashcmp(co->sha1, sha1))
return co;
}
if (!hashcmp(sha1, empty_tree.sha1))
return &empty_tree;
return NULL;
}

Expand Down
69 changes: 69 additions & 0 deletions t/t3701-add-interactive.sh
@@ -0,0 +1,69 @@
#!/bin/sh

test_description='add -i basic tests'
. ./test-lib.sh

test_expect_success 'setup (initial)' '
echo content >file &&
git add file &&
echo more >>file &&
echo lines >>file
'
test_expect_success 'status works (initial)' '
git add -i </dev/null >output &&
grep "+1/-0 *+2/-0 file" output
'
cat >expected <<EOF
new file mode 100644
index 0000000..d95f3ad
--- /dev/null
+++ b/file
@@ -0,0 +1 @@
+content
EOF
test_expect_success 'diff works (initial)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/new file/,/content/p" <output >diff &&
diff -u expected diff
'
test_expect_success 'revert works (initial)' '
git add file &&
(echo r; echo 1) | git add -i &&
git ls-files >output &&
! grep . output
'

test_expect_success 'setup (commit)' '
echo baseline >file &&
git add file &&
git commit -m commit &&
echo content >>file &&
git add file &&
echo more >>file &&
echo lines >>file
'
test_expect_success 'status works (commit)' '
git add -i </dev/null >output &&
grep "+1/-0 *+2/-0 file" output
'
cat >expected <<EOF
index 180b47c..b6f2c08 100644
--- a/file
+++ b/file
@@ -1 +1,2 @@
baseline
+content
EOF
test_expect_success 'diff works (commit)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/^index/,/content/p" <output >diff &&
diff -u expected diff
'
test_expect_success 'revert works (commit)' '
git add file &&
(echo r; echo 1) | git add -i &&
git add -i </dev/null >output &&
grep "unchanged *+3/-0 file" output
'

test_done

0 comments on commit c484166

Please sign in to comment.